import UIKit

var str = "Hello, playground"

class Student {
    //定义姓名和年龄为变量的存储属性,可以修改
    var name:String
    var age:Int
    
    //定义性别为常量存储属性,一旦实例构造出啦IU就不能进行修改
    let sex:String
    
    //定义一个学校的存储属性,默认值为北京一中
    var school = "北京一中"
    
    //构造方法
    init(name:String,age:Int,sex:String) {
        self.name = name
        self.age = age
        self.sex = sex
    }
}

//在类中有一个原则，即当类实例被构造完成时，必须保证类中所有的属性都构造或者初始化完成。
//因此，一般情况下开发者会在创建的类中提供一个构造方法，用于设置其中的属性，
//但并不是所有情况都需要这么做，我们也可以为类中的属性在声明时就提供一个初始值，
//例如学生定义一个所在学校名称的属性，并为其提供默认值

//Swift语言支持将存储属性设置为延时存储属性。
//所谓延时存储属性就是指在类实例构造的时候，延时存储属性并不进行构造或初始化，
//只有当开发者调用到类实例的这个属性时，此属性才完成构造或初始化操作。
//延时存储属性在开发中很有优势，例如一个类的某个属性可能是一种复杂的数据对象，
//这个属性要完成构造可能需要花费很长的时间，将其设置为延时构造属性将大大减少类实例的构造时间。
class Work {
    var name:String
    init(name:String) {
        self.name = name
        print("完成了work类实例的构造")
    }
}

class People{
    var age:Int
    lazy var work:Work = Work(name: "teacher")
    init(age:Int) {
        self.age = age
    }
}
//构造People类的实例,并没有打印Work了的构造信息
var people = People(age: 24)
//使用work属性时,才完成work实例的构造
print(people.work.name)


//与存储属性相比，计算属性更像是运算过程。
//举个例子，创建一个圆形类，类中定义圆心与半径两个存储属性。
//为了方便使用，开发者可以将圆的周长与面积也定义为属性，
//但是圆的周长和面积可以通过半径来计算，
//所以这里实际上无须再定义额外的存储属性。
//Swift语言中提供了计算属性，用来描述这种可以由其他属性通过计算而得到的属性

class Circle {
    //提供两个存储属性
    var r:Double
    var center:(Double,Double)
    //提供周长与面积的计算属性
    var l:Double{
        get{
            return 2*r*Double.pi
        }
        set{
            r = newValue/2/Double.pi
        }
    }
    
    var area:Double {
        get{
            return r*r*Double.pi
        }
        set{
//            r = sqrt(newValue/Double.pi)//开平方方法报错,原因待查找
        }
    }
    
    //构造方法
    init(r:Double,center:(Double,Double)) {
        self.r = r
        self.center = center
    }
}

//创建圆类的实例对象
var circle1 = Circle(r: 4, center: (2,2))
//通过计算属性获取周长与面积
print("周长是:\(circle1.l),面积是:\(circle1.area)")
